//
// Created by 吴喆 on 2020/3/26.
//

#ifndef SUMMER_STATEMACHINE_H
#define SUMMER_STATEMACHINE_H


#include <map>
#include "Input.h"
#include "Animation.h"

class PlayableState;
class Playable;

class StateMachine {
public:
    StateMachine() = default;

    virtual ~StateMachine();

    PlayableState *currentState = nullptr;

    void update(Playable &playable);

    void handleInput(Playable &playable, KeyEvent *pEvent);

private:
    bool summerFirst = true;
};

class PlayableState {
public:
    PlayableState() = default;

    virtual ~PlayableState() {
        for (auto item : animationMap) {
            delete item.second;
        }
    }

    /**
     * invoked while keyboard input
     *
     * @param playable the object that has this state
     * @param keyEvent the key event
     * @return
     */
    virtual PlayableState *handleInput(Playable &playable, KeyEvent *keyEvent);

    /**
     * invoked while {@code Playable} update
     *
     * @param playable the object that has this state
     * @return if state changed, return new state, else nullptr
     */
    virtual PlayableState *update(Playable &playable);

    /**
     * init animation
     */
    virtual void initAnimation() {};

    /**
     * invoked while state begin
     *
     * @param playable object that have this state
     */
    virtual void enter(Playable &playable);

    /**
     * to store animation, the animationMap[0] is default animation to play
     */
    std::map<int, Animation *> animationMap;

};

#endif //SUMMER_STATEMACHINE_H
